#include <csi_core.h>

#define INDIRECT_MAX_SIZE   (128 * 1024)
#define AHB_ADDR_RANGE      (0x0F) 
#define QSPIFLASH_DMA_CH 0

extern volatile uint8_t dma_cb_flag;

typedef struct 
{
    uint32_t src_addr;
    uint32_t dst_addr;
    uint32_t llp;
    uint32_t CTL_low;
    uint32_t CTL_high;
}dmac_linked_t;

typedef struct {
    __IOM uint32_t QSPI_CONFIGURATION;       /* Offset: 0x000 (R/W)  Control register 0 */
    __IOM uint32_t DEVICE_READ_INSTRUCTION;  /* Offset: 0x004 (R/W)  device read instruction register */
    __IOM uint32_t DEVICE_WRITE_INSTRUCTION; /* Offset: 0x008 (R/W)  device read instruction register */
    __IOM uint32_t DEVICE_DELAY;             /* Offset: 0x00C (R/W)  device read instruction register */
    __IOM uint32_t READ_DATA_CAPTURE;        /* Offset: 0x010 (R/W)  device read instruction register */
    __IOM uint32_t DEVIC_SIZE_CONFIG;        /* Offset: 0x014 (R/W)  device read instruction register */
    __IOM uint32_t SRAM_PARTITION_CONFIG;    /* Offset: 0x018 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_AHB_ADDR_TRIGGER;/* Offset: 0x01C (R/W)  device read instruction register */
    __IOM uint32_t DMA_PERIPHERAL_CONFIG;    /* Offset: 0x020 (R/W)  device read instruction register */
    __IOM uint32_t REMAP_ADDR;               /* Offset: 0x024 (R/W)  device read instruction register */
    __IOM uint32_t MODE_BIT_CONFIG;          /* Offset: 0x028 (R/W)  device read instruction register */
    __IOM uint32_t SRAM_FILL_LEVEL;          /* Offset: 0x02C (R/W)  device read instruction register */
    __IOM uint32_t TX_THRESHOLD;             /* Offset: 0x030 (R/W)  device read instruction register */
    __IOM uint32_t RX_THRESHOLD;             /* Offset: 0x034 (R/W)  device read instruction register */
    __IOM uint32_t WRITE_COMPLETION_CONTROL; /* Offset: 0x038 (R/W)  device read instruction register */
    __IOM uint32_t POLLING_EXPIRATION;       /* Offset: 0x03C (R/W)  device read instruction register */
    __IOM uint32_t INTERRUPT_STATUS;         /* Offset: 0x040 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED0;                /* Offset: 0x044 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED1;                /* Offset: 0x048 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED2;                /* Offset: 0x04C (R/W)  device read instruction register */
    __IOM uint32_t LOWER_WRITE_PROTECTION;   /* Offset: 0x050 (R/W)  device read instruction register */
    __IOM uint32_t UPPER_WRITE_PROTECTION;   /* Offset: 0x054 (R/W)  device read instruction register */
    __IOM uint32_t WRITE_PROTECTION;         /* Offset: 0x058 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED3;                /* Offset: 0x05C (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_READ_TRANSFER_CONTROL;    /* Offset: 0x060 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_READ_TRANS_WATERMARK;     /* Offset: 0x064 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_READ_TRANS_START_ADDR;    /* Offset: 0x068 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_READ_TRANS_NUM_BYTES;     /* Offset: 0x06C (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_WRITE_TRANSFER_CONTROL;   /* Offset: 0x070 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_WRITE_TRANS_WATERMARK;    /* Offset: 0x074 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_WRITE_TRANS_START_ADDR;   /* Offset: 0x078 (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_WRITE_TRANS_NUM_BYTES;    /* Offset: 0x07C (R/W)  device read instruction register */
    __IOM uint32_t INDIRECT_TRIGGER_ADDR_RANGE;       /* Offset: 0x080 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED4;                         /* Offset: 0x084 (R/W)  device read instruction register */
    __IOM uint32_t RESERVED5;                         /* Offset: 0x088 (R/W)  device read instruction register */
    __IOM uint32_t FLASH_CMD_CONTROL_MEMORY;          /* Offset: 0x08C (R/W)  device read instruction register */
    __IOM uint32_t FLASH_COMMAND_CONTROL;          /* Offset: 0x090 (R/W)  Control register 0 */
    __IOM uint32_t FLASH_COMMAND_ADDR;             /* Offset: 0x094 (R/W)  Control register 0 */
    __IOM uint32_t RESERVED6;                      /* Offset: 0x098 (R/W)  Control register 0 */
    __IOM uint32_t RESERVED7;                      /* Offset: 0x09C (R/W)  Control register 0 */
    __IOM uint32_t FLASH_COMMAND_READL;     /* Offset: 0x0a0 (R/W)  Control register 0 */
    __IOM uint32_t FLASH_COMMAND_READH;     /* Offset: 0x0a4 (R/W)  Control register 0 */
    __IOM uint32_t FLASH_COMMAND_WRITEL;    /* Offset: 0x0a8 (R/W)  Control register 0 */
    __IOM uint32_t FLASH_COMMAND_WRITEH;    /* Offset: 0x0ac (R/W)  Control register 0 */
    __IOM uint32_t POLLING_FLASH_STATUS;    /* Offset: 0x0B0 (R/W)  Control register 0 */
    __IOM uint32_t MODULE_ID;               /* Offset: 0x0B0 (R/W)  Control register 0 */
} cd_qspi_ctrl_reg_t;

void indirect_memcpy(uint8_t* dest_addr, uint8_t* addr_offset, uint32_t len);
int indirect_memcpy_dma(uint8_t *dest_addr, uint8_t *addr_offset, uint32_t len);
int indirect_memcpy_dma_linked(uint8_t *dest_addr, uint8_t *addr_offset, uint32_t len);
int test_qspiflash_copy_dmac_mode(void);
